package br.com.gerenciamento.pg.framework.core.service.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Persistable;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import br.com.gerenciamento.pg.framework.core.service.IEntityService;
import br.com.gerenciamento.pg.framework.jpa.eclipselink.repository.FindByExampleRepository;
import br.com.gerenciamento.pg.framework.jpa.repository.CrudSpecificationRepository;

@Transactional(readOnly = true, propagation = Propagation.REQUIRED)
public abstract class AbstractEntityService<T extends Persistable<ID>, ID extends Serializable> implements IEntityService<T, ID> {

	protected abstract CrudSpecificationRepository<T, ID> getRepository();
    
    @Autowired
    private FindByExampleRepository<T> findByExampleRepository;

    @Transactional(readOnly = false)
    public <S extends T> S save(S s) {
        return getRepository().save(s);
    }

    @Transactional(readOnly = false)
    public <S extends T> List<S> save(Iterable<S> itrbl) {
        Iterable<S> iterable = getRepository().save(itrbl);
        List<S> lista = new ArrayList<S>();
        for (Iterator<S> it = iterable.iterator(); it.hasNext();) {
            S s = it.next();
            lista.add(s);
        }
        return lista;
    }

    public T findOne(ID id) {
        return getRepository().findOne(id);
    }

    public boolean exists(ID id) {
        return getRepository().exists(id);
    }

    public List<T> findAll() {
        Iterable<T> iterable = getRepository().findAll();
        List<T> lista = new ArrayList<T>();
        for (Iterator<T> it = iterable.iterator(); it.hasNext();) {
            T t = it.next();
            lista.add(t);
        }
        return lista;
    }

    public List<T> findAll(Iterable<ID> itrbl) {
        Iterable<T> iterable = getRepository().findAll(itrbl);
        List<T> lista = new ArrayList<T>();
        for (Iterator<T> it = iterable.iterator(); it.hasNext();) {
            T t = it.next();
            lista.add(t);
        }
        return lista;
    }

    public long count() {
        return getRepository().count();
    }

    @Transactional(readOnly = false)
    public void delete(ID id) {
        getRepository().delete(id);
    }

    @Transactional(readOnly = false)
    public void delete(T t) {
        getRepository().delete(t);
    }

    @Transactional(readOnly = false)
    public void delete(Iterable<? extends T> itrbl) {
        getRepository().delete(itrbl);
    }

    @Transactional(readOnly = false)
    public void deleteAll() {
        getRepository().deleteAll();
    }

    public List<T> findByExample(T example) {
        return findByExampleRepository.findByExample(example);
    }
    
    
}
